package com.example.api.sentinel;

import com.alibaba.csp.sentinel.slots.block.AbstractRule;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.csp.sentinel.slots.system.SystemBlockException;
import com.alibaba.fastjson.JSON;
import com.example.common.entity.ResultDO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @program: cc-web
 * @description: 异常降级响应
 * @author: meihua
 * @created: 2020/11/24 09:46
 */
public class FallbackHandlerResponse {

    private static final Logger logger = LoggerFactory.getLogger(FallbackHandlerResponse.class);

    /**
     * @Author meihua
     * @Description 流控异常响应
     * @Date 13:45 2020/11/24
     * @Param  Throwable
     * @return ResultDO
     **/
    public static ResultDO defaultFallbackResponse(Throwable e){
        if(e instanceof FlowException){
            FlowException ex = (FlowException) e;
            logger.warn("sentinel  FlowException  触发资源限流规则 {}",getResourceInfo(ex.getRule()));
            return  new ResultDO(false, "当前访问人数过多，请稍后再试!");
        }else if(e instanceof DegradeException){
            DegradeException ex = (DegradeException) e;
            logger.warn("sentinel DegradeException {} 触发资源降级 {}",e.getMessage(),getResourceInfo(ex.getRule()));
            return  new ResultDO(false, "服务出现异常，请稍后再试~");
        }else if (e instanceof SystemBlockException) {
            SystemBlockException ex = (SystemBlockException) e;
            logger.warn("sentinel  SystemBlockException {} 触发系统保护规则 {}",e.getMessage(),getResourceInfo(ex.getRule()));
            return  new ResultDO(false, "系统出现异常，请稍后再试~");
        } else if(e instanceof ParamFlowException){
            ParamFlowException ex = (ParamFlowException) e;
            logger.warn("sentinel ParamFlowException 热点参数限流 资源名={} 参数={} {}", ex.getResourceName(), ex.getLimitParam(), getResourceInfo(ex.getRule()));
            return  new ResultDO(false, "热点参数限流" + e.getMessage());
        } else if(e instanceof AuthorityException){
            AuthorityException ex = (AuthorityException) e;
            logger.warn("sentinel AuthorityException 授权规则不通过 {}", getResourceInfo(ex.getRule()));
            return  new ResultDO(false, "授权规则不通过");
        }
       logger.error("Exception : {}  message:{}",e, e.getMessage());

       throw new RuntimeException("error " + e.getClass().getName() + ":" + e.getMessage());
    }

    public static  String  getResourceInfo(AbstractRule rule){
        String  origin = rule.getLimitApp();
        String resource = rule.getResource();
        return String.format("资源名称:%s, 调用方:%s, 规则:%s", resource, origin,  JSON.toJSONString(rule));
    }

}
